---
title: ApolloStore
---

Apollo Kotlin exposes the `ApolloStore` API to read and write from the normalized cache programmatically. The `ApolloStore` sits on top of `NormalizedCache`, exposes a thread safe API as well as methods that make it easier to read and write fragments and operations.

The store is accessible with the `ApolloClient.apolloStore` extension:

```kotlin
val apolloClient = ApolloClient.Builder()
  .serverUrl("https://example.com/graphql")
  .normalizedCache(MemoryCacheFactory(maxSizeBytes = 10 * 1024 * 1024))
  .build()

val apolloStore: ApolloStore = apolloClient.apolloStore
```

Note that the read and write operations are synchronous and might block if the underlying cache is doing IO (such as the [SQLite cache](../caching/normalized-cache#sqlite-cache)).
Therefore calling them from the main thread should be avoided.

## Reading operation data

Just like a regular GraphQL query, the main way to use the store is to read and write queries:

Given the following query:

```graphql
query GetBook($id: String!) {
  book(id: $id) {
    title
    author {
      name
    }
  }
}
```

You can read it like this:

```kotlin
val data = apolloClient.apolloStore.readOperation(GetBookQuery(id = "42"), apolloClient.customScalarAdapters)

println("Title=${data.title}")
println("Author Name=${data.author.name}")
```

In the event of cache miss, `readOperation` will throw:

```kotlin
try {
  apolloClient.apolloStore.readOperation(GetBookQuery(id = "42"), apolloClient.customScalarAdapters)
} catch(e: CacheMissException) {
  println("CacheMiss on key: ${e.key}.${e.fieldName}")
}
```

> If you declared [scalar adapters](../essentials/custom-scalars/) at runtime, pass your client's `customScalarAdapters` to the store's methods, as the store will need them to convert scalar values to and from their Kotlin/Java types.

## Writing operation data

Writing operation data is similar to reading:

```kotlin
apolloClient.apolloStore.writeOperation(GetBookQuery(id = "42"), data, apolloClient.customScalarAdapters)
```

Note how you'll need to pass the data along the operation.

## Reading and Writing fragments

In the [GraphQL specification](https://spec.graphql.org/draft/), fragments are always part of a larger operation and cannot be executed standalone.

```graphql
fragment BookDetails on Book {
  id
  title
  author {
    name
  }
}
```

Apollo Kotlin makes an exception to that rule and allows to read/write individual fragments. This is disabled by default and can be enabled with `generateFragmentImplementations`:

```kotlin
apollo {
  service("service") {
    generateFragmentImplementations.set(true)
  }
}
```

Because fragments are not rooted, you need to specify the root cache id of the fragment:

```kotlin
val data = apolloClient.apolloStore.readFragment(BookDetailsImpl(), CacheKey("42"), apolloClient.customScalarAdapters)

println("Title=${data.title}")
println("Author Name=${data.author.name}")
```

Fragments can contain variables. Different fragments with different variables can return different data. In that case the fragment `Impl` class will require variables as constructor parameters:

```graphql
fragment BookDetails on Book {
  id
  title(locale: $locale)
}
```

```kotlin
val data = apolloClient.apolloStore.readFragment(BookDetailsImpl(locale = "en-US"), CacheKey("42"), apolloClient.customScalarAdapters)

println("Title=${data.title}")
```

## Clearing the cache

Call `apolloClient.apolloStore.clearAll()` to clear the cache of all entries.
